package com.grow.greenhouse.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.grow.greenhouse.auth.AESBase64Utils;
import com.grow.greenhouse.auth.IoTConsumer;
import com.grow.greenhouse.auth.IoTMessage;
import com.grow.greenhouse.common.WebSocket;
import com.grow.greenhouse.config.IoTConfig;
import com.grow.greenhouse.domain.Equipdailynum;
import com.grow.greenhouse.domain.properties.IoTProperties;
import com.grow.greenhouse.once.UserContext;
import com.grow.greenhouse.service.EquipdailynumService;
import com.grow.greenhouse.service.HistoryexceptionService;
import com.grow.greenhouse.service.UserService;
import com.grow.greenhouse.service.UserthreholdService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class IoTService {

    @Resource
    private IoTProperties iotProperties;

    @Resource
    private EquipdailynumService equipdailynumService;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private HistoryexceptionService historyexceptionService;

    @Resource
    private UserthreholdService userthreholdService;

    @Resource
    private UserService userService;

    @PostConstruct
    public void init(){
        Executors.newSingleThreadExecutor().submit(this::startIoTConsumer);
    }

    private volatile Map<String,String> lastValueMap = new HashMap<>();

    public void startIoTConsumer() {
        // 确保所有配置都已提供
        if (iotProperties.getAccessId() == null || iotProperties.getSecretKey() == null
                || iotProperties.getSubscriptionName() == null) {
            log.error("IoT configuration is missing");
            return;
        }

        IoTConsumer iotConsumer = IoTConsumer.IOTConsumerBuilder.anIOTConsumer()
                .brokerServerUrl(IoTConfig.brokerSSLServerUrl)
                .iotAccessId(iotProperties.getAccessId())
                .iotSecretKey(iotProperties.getSecretKey())
                .subscriptionName(iotProperties.getSubscriptionName())
                .iotMessageListener(message -> {
                    // 这里添加你的消息监听逻辑
                    String payload = new String(message.getData());
                    IoTMessage iotMessage= JSONObject.parseObject(payload, IoTMessage.class);
                    String originalMsg= AESBase64Utils.decrypt(iotMessage.getData(),
                            iotProperties.getSecretKey().substring(8,24));
                    log.info("PayLoad:"+payload);
                    Map<String,String> translateMap = Stream.of(new String[][]{
                            {"Air_humi","空气湿度"},
                            {"Light_intensity","光照强度"},
                            {"Air_temp","空气温度"},
                            {"Soil_PH","土壤PH值"},
                            {"CO2","二氧化碳"},
                            {"Soil_temp","土壤温度"},
                            {"Soil_humi","土壤湿度"}

                    }).collect(Collectors.toMap(data -> data[0],data -> data[1]));

                    Map<String,String> databaseMap = Stream.of(new String[][]{
                            {"Air_humi","airMoisture"},
                            {"Light_intensity","illumination"},
                            {"Air_temp","airTemp"},
                            {"Soil_PH","PHvalue"},
                            {"CO2","carbonDioxide"},
                            {"Soil_temp","soilTemp"},
                            {"Soil_humi","soilMoisture"}
                    }).collect(Collectors.toMap(data -> data[0],data -> data[1]));
                    JSONObject params = JSONObject.parseObject(originalMsg)
                            .getJSONObject("subData").
                            getJSONObject("params");

//                    for (int i = 0; i < jsonArray.size(); i++) {
//                        JSONObject jsonObject = jsonArray.getJSONObject(i);
//                        JSONObject newJsonObject = new JSONObject();
//                        for(String key : jsonObject.keySet()){
//                            JSONObject valueObject = jsonObject.getJSONObject(key);
//                            newJsonObject.put(translateMap.getOrDefault(key, key), valueObject.get("value").toString());
//                            lastValueMap.put(databaseMap.getOrDefault(key, key), valueObject.get("value").toString());
//                        }
//                        jsonArray.set(i,newJsonObject);
//                    }
                    // 新的JSONArray来存放转换后的数据
                    JSONArray newJsonArray = new JSONArray();
                    for (String key : params.keySet()) {
                        JSONObject singleParam = params.getJSONObject(key);
                        JSONObject newJsonObject = new JSONObject();
                        // 将英文字段名翻译成中文字段名
                        String translatedKey = translateMap.getOrDefault(key, key);
                        lastValueMap.put(databaseMap.getOrDefault(key,key),singleParam.get("value").toString());
                        newJsonObject.put("name",translatedKey);
                        newJsonObject.put("data",singleParam.get("value").toString());
                        newJsonArray.add(newJsonObject);
                    }

//                    lastValueMap.forEach((key,value)->
//                            rabbitTemplate.convertAndSend("Exception_Check",new Pair<>(key,value)));
                    rabbitTemplate.convertAndSend("Exception_Check",lastValueMap);

                    WebSocket.sendInfo(newJsonArray.toJSONString());

                    log.info("SubData:"+newJsonArray);
                    log.info("OriginalMsg:"+originalMsg);
                })
                .build();

        try {
            iotConsumer.run();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Scheduled(cron = "0 0 * * * * ")
    public void doSaveHourlyData(){
        int hour = LocalTime.now().getHour();
        Equipdailynum equipdailynum = new Equipdailynum();
        lastValueMap.forEach((key,value)->{
            equipdailynum.setUserId(UserContext.getUserId());
            equipdailynum.setTime(hour);
            equipdailynum.setIndicatorName(key);
            equipdailynum.setDataValue(Double.valueOf(value));
            equipdailynum.setBelongShedName("测试");
            equipdailynumService.saveOrUpdate(equipdailynum);
        });
    }
}
